package com.fbs.job.admin.controller;
import com.fbs.job.admin.core.entity.FbsJobActuator;
import com.fbs.job.admin.core.entity.FbsJobInfo;
import com.fbs.job.admin.core.entity.FbsJobUser;
import com.fbs.job.admin.core.enums.*;
import com.fbs.job.admin.core.thread.JobScheduleHelper;
import com.fbs.job.admin.core.thread.JobTriggerPoolHelper;
import com.fbs.job.admin.mapper.FbsJobActuatorMapper;
import com.fbs.job.admin.service.JobInfoService;
import com.fbs.job.admin.service.JobUserService;
import com.fbs.job.core.enums.ExecutorBlockStrategyEnum;
import com.fbs.job.core.glue.GlueTypeEnum;
import com.fbs.job.core.model.ResultT;
import com.fbs.job.core.util.DateTool;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
@Controller
@RequestMapping("/job_info")
public class JobInfoController {

    @Resource
    private FbsJobActuatorMapper fbsJobActuatorMapper;
    @Resource
    private JobInfoService jobInfoService;


    @RequestMapping
    public String index(HttpServletRequest request,Model model,@RequestParam(required = false, defaultValue = "-1") int jobActuator) {

        // 执行器列表
        List<FbsJobActuator> jobActuatorList_all =  fbsJobActuatorMapper.findAll();
        List<FbsJobActuator> jobActuatorList = filterJobActuatorByRole(request, jobActuatorList_all);
        if (jobActuatorList==null || jobActuatorList.size()==0) {
            throw new RuntimeException("不存在有效执行器,请联系管理员");
        }

        model.addAttribute("jobActuatorList", jobActuatorList);
        model.addAttribute("jobActuator", jobActuator);


        model.addAttribute("ScheduleTypeEnum", ScheduleTypeEnum.values());
        model.addAttribute("GlueTypeEnum", GlueTypeEnum.values());
        model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values());
        model.addAttribute("MisfireStrategyEnum", MisfireStrategyEnum.values());
        model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values());

        return "info/jobinfo";
    }

    @RequestMapping("/add")
    @ResponseBody
    public ResultT<String> add(@RequestBody FbsJobInfo jobInfo) {
        return jobInfoService.add(jobInfo);
    }

    @RequestMapping("/update")
    @ResponseBody
    public ResultT<String> update(@RequestBody FbsJobInfo jobInfo) {
        return jobInfoService.update(jobInfo);
    }

    public static class TriggerJobReq{
        int id;
        String executorParam;
        String addressList;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getExecutorParam() {
            return executorParam;
        }

        public void setExecutorParam(String executorParam) {
            this.executorParam = executorParam;
        }

        public String getAddressList() {
            return addressList;
        }

        public void setAddressList(String addressList) {
            this.addressList = addressList;
        }
    }
    @RequestMapping("/stop")
    @ResponseBody
    public ResultT<String> pause(int id) {
        return jobInfoService.stop(id);
    }

    @RequestMapping("/start")
    @ResponseBody
    public ResultT<String> start(int id) {
        return jobInfoService.start(id);
    }

    @RequestMapping("/delete")
    @ResponseBody
    public ResultT<String> remove(int id) {
        return jobInfoService.delete(id);
    }




    @RequestMapping("/trigger")
    @ResponseBody
    //@PermissionLimit(limit = false)
    public ResultT<String> triggerJob(@RequestBody TriggerJobReq req) {
        // force cover job param
        if (req.getExecutorParam() == null) {
            req.setExecutorParam("");
        }

        JobTriggerPoolHelper.trigger(req.getId(), TriggerTypeEnum.MANUAL, -1, null, req.getExecutorParam(), req.getAddressList());
        return ResultT.success();
    }


    @RequestMapping("/pageList")
    @ResponseBody
    public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int page,
                                        @RequestParam(required = false, defaultValue = "10") int rows,
                                        String jobActuator, String triggerStatus, String jobDesc, String executorHandler, String author) {
        // 分页列表
        return jobInfoService.pageList(page, rows, Integer.valueOf(jobActuator), Integer.valueOf(triggerStatus), jobDesc, executorHandler, author);
    }



    @RequestMapping("/nextTriggerTime")
    @ResponseBody
    public ResultT<List<String>> nextTriggerTime(String scheduleType, String scheduleConf) {

        FbsJobInfo paramFbsJobInfo = new FbsJobInfo();
        paramFbsJobInfo.setScheduleType(scheduleType);
        paramFbsJobInfo.setScheduleConf(scheduleConf);

        List<String> result = new ArrayList<>();
        try {
            Date lastTime = new Date();
            for (int i = 0; i < 5; i++) {
                lastTime = JobScheduleHelper.generateNextValidTime(paramFbsJobInfo, lastTime);
                if (lastTime != null) {
                    result.add(DateTool.getYMDHMS(lastTime));
                } else {
                    break;
                }
            }
        } catch (Exception e) {
            return new ResultT<List<String>>(ResultT.FAIL_CODE, "非法错误");
        }
        return  ResultT.success(result);

    }







    public static void validPermission(HttpServletRequest request, int jobGroup) {
        FbsJobUser loginUser = (FbsJobUser) request.getAttribute(JobUserService.LOGIN_IDENTITY_KEY);
        if (!loginUser.validPermission(jobGroup)) {
            throw new RuntimeException("权限拦截" + "[username="+ loginUser.getUsername() +"]");
        }
    }


    public static List<FbsJobActuator> filterJobActuatorByRole(HttpServletRequest request, List<FbsJobActuator> jobActuatorList_all){
        List<FbsJobActuator> jobActuatorList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(jobActuatorList_all)) {
            FbsJobUser loginUser = (FbsJobUser) request.getAttribute(JobUserService.LOGIN_IDENTITY_KEY);
            if (loginUser.getRole() == 1) {
                jobActuatorList = jobActuatorList_all;
            } else {
                List<String> groupIdsList = new ArrayList<>();
                if (loginUser.getPermission()!=null && loginUser.getPermission().trim().length()>0) {
                    groupIdsList = Arrays.asList(loginUser.getPermission().trim().split(","));
                }
                for (FbsJobActuator actuator:jobActuatorList_all) {
                    if (groupIdsList.contains(String.valueOf(actuator.getId()))) {
                        jobActuatorList.add(actuator);
                    }
                }
            }
        }
        return jobActuatorList;
    }

}
